home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
System Booster
/
System Booster.iso
/
Screenblankers
/
FT
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-26
|
19KB
|
834 lines
/*--------------------------------------------------------------------------*/
/* */
/* F l y i n g T o a s t e r s */
/* */
/* */
/* */
/*--------------------------------------------------------------------------*/
/* MAIN.c */
/*--------------------------------------------------------------------------*/
#define MAIN_C
#if ! defined(HEADER_PROCOMPILED)
# include "include.h"
#endif
#include "ft.h"
#include "main.h"
/*--------------------------------------------------------------------------
G L O B A L S
--------------------------------------------------------------------------*/
BOOLEAN volatile blanked = FALSE,
prefs_open = FALSE;
BOOLEAN initial_popup = FALSE;
UCHAR *ver = VERSIONSTRING,
**tooltypes;
UINT volatile nr_objects;
ULONG volatile timeout_ticks,
delay_rate,
priority;
LONG volatile mouse_timeout;
enum CORNER volatile csleep,
cnever;
UCHAR *blank_key,
*popup_key;
struct Library *GadToolsBase,
*CxBase,
*IconBase;
struct Task *main_task;
CxObj *hotkeyfilter,
*broker;
struct MsgPort *ft_port,
*cxport;
struct object ft[OBJECTMAX];
struct NewBroker newbroker = {
NB_VERSION,
PROG_NAME,
PROG_TITLE,
PROG_DESCR,
NBU_NOTIFY | NBU_UNIQUE,
COF_SHOW_HIDE,
0,NULL,0
};
struct sequence *seq_list[] = {
NULL, // free flight
&default_seq,
&loop_seq,
&face_seq
};
// detach code
LONG _stack = 2048L;
UCHAR *_procname = PROG_NAME;
LONG _priority = 0L;
LONG _BackGroundIO = 1L;
GLOBAL BPTR _Backstdout;
/*--------------------------------------------------------------------------*/
/* init_ftmsg */
/*--------------------------------------------------------------------------*/
struct ft_msg * init_ftmsg(enum BLANKERACTION action)
{
struct ft_msg *ft_msg;
if ((ft_msg = (struct ft_msg *) calloc(1,sizeof(*ft_msg))) != NULL) {
ft_msg->ftm_msg.mn_Node.ln_Type = NT_MESSAGE;
ft_msg->ftm_msg.mn_Length = sizeof(*ft_msg);
ft_msg->ftm_action = action;
}
return(ft_msg);
} /* init_ftmsg */
/*--------------------------------------------------------------------------*/
/* mouse_in_corner */
/*--------------------------------------------------------------------------*/
LOCAL BOOLEAN mouse_in_corner(enum CORNER corner)
{
INT mx,my,
x,y,
w,h;
ULONG ilock;
if (corner == CO_DISABLED)
return(FALSE);
ilock = LockIBase(0L);
mx = IntuitionBase->MouseX;
my = IntuitionBase->MouseY;
x = IntuitionBase->ActiveScreen->LeftEdge;
y = IntuitionBase->ActiveScreen->TopEdge;
w = IntuitionBase->ActiveScreen->Width - MOUSE_WIDTH;
h = IntuitionBase->ActiveScreen->Height - MOUSE_HEIGHT;
UnlockIBase(ilock);
switch (corner) {
case CO_TOPLEFT:
return((BOOLEAN) (mx <= (x + MOUSE_WIDTH) && my <= (y + MOUSE_HEIGHT)));
break;
case CO_TOPRIGHT:
return((BOOLEAN) (mx >= (x + w) && my <= (y + MOUSE_HEIGHT)));
break;
case CO_BOTTOMLEFT:
return((BOOLEAN) (mx <= (x + MOUSE_WIDTH) && my >= (y + h)));
break;
case CO_BOTTOMRIGHT:
return((BOOLEAN) (mx >= (x + w) && my >= (y + h)));
break;
} // switch
} /* mouse_in_corner */
/*--------------------------------------------------------------------------*/
/* dispatch_cx */
/*--------------------------------------------------------------------------*/
void __stdargs __saveds dispatch_cx(CxMsg *CxMessage,CxObj *CxObject)
{
static BOOLEAN mouse_blanked = FALSE;
static ULONG timer_ticks = 0L;
struct InputEvent *event;
struct ft_msg *ft_msg;
event = (struct InputEvent *) CxMsgData(CxMessage);
if (blanked) {
if ((event->ie_Class == IECLASS_RAWKEY &&
(event->ie_Code & IECODE_UP_PREFIX) == 0 &&
(event->ie_Qualifier & IEQUALIFIER_REPEAT) == 0) ||
event->ie_Class == IECLASS_RAWMOUSE) {
timer_ticks = 0L;
mouse_blanked = FALSE;
if ((ft_msg = init_ftmsg(BA_WAIT)) != NULL)
PutMsg(ft_port,(struct Message *) ft_msg);
}
return;
}
if (event->ie_Class == IECLASS_TIMER) { // process timer event
timer_ticks++;
if (timer_ticks == timeout_ticks) {
if (! mouse_in_corner(cnever) && (ft_msg = init_ftmsg(BA_BLANK)) != NULL)
PutMsg(ft_port,(struct Message *) ft_msg);
return;
}
else if (timer_ticks == CORNER_TIMEOUT &&
mouse_in_corner(csleep) &&
(ft_msg = init_ftmsg(BA_BLANK)) != NULL) {
PutMsg(ft_port,(struct Message *) ft_msg);
}
else if (mouse_timeout != -1L && (LONG) timer_ticks == mouse_timeout) {
WaitTOF();
OFF_SPRITE;
custom.spr[0].dataa = 0;
custom.spr[0].datab = 0;
mouse_blanked = TRUE;
}
return;
}
timer_ticks = 0L; // reset ticks
if (mouse_blanked && event->ie_Class != IECLASS_RAWKEY) {
ON_SPRITE;
mouse_blanked = FALSE;
}
else if (mouse_timeout != -1L && ! mouse_blanked && event->ie_Class == IECLASS_RAWKEY) {
WaitTOF();
OFF_SPRITE;
custom.spr[0].dataa = 0;
custom.spr[0].datab = 0;
mouse_blanked = TRUE;
}
} /* dispatch_cx */
/*--------------------------------------------------------------------------*/
/* create_process */
/*--------------------------------------------------------------------------*/
struct Process *create_process(UCHAR *pname, void (*func) (void), BOOLEAN cli)
{
struct TagItem tag[7];
tag[0].ti_Tag = NP_Entry;
tag[0].ti_Data = (Tag) func;
tag[1].ti_Tag = NP_Name;
tag[1].ti_Data = (Tag) pname;
tag[2].ti_Tag = NP_Output;
tag[2].ti_Data = (Tag) Open("*",MODE_NEWFILE);
tag[3].ti_Tag = NP_Cli;
tag[3].ti_Data = (Tag) cli;
tag[4].ti_Tag = NP_Priority;
tag[4].ti_Data = (Tag) priority;
tag[5].ti_Tag = NP_StackSize;
tag[5].ti_Data = (Tag) 3000;
tag[6].ti_Tag = TAG_DONE;
return(CreateNewProc(tag));
} /* create_process */
/*--------------------------------------------------------------------------*/
/* open_cxstuff */
/*--------------------------------------------------------------------------*/
BOOLEAN open_cxstuff(void)
{
CxObj *obj;
if ((cxport = CreatePort(CX_PORT_NAME,0L)) == NULL) {
dbprintf("no cx port\n");
return(FALSE);
}
newbroker.nb_Pri = 0;
newbroker.nb_Port = cxport;
if((broker = CxBroker(&newbroker,NULL)) == NULL) {
dbprintf("no broker\n");
return(FALSE);
}
if ((obj = HotKey(blank_key,cxport,BA_BLANK)) == NULL) {
dbprintf("cx failed (1)\n");
return(FALSE);
}
AttachCxObj(broker,obj);
if ((obj = HotKey(popup_key,cxport,BA_POPUP_PREFS)) == NULL) {
dbprintf("cx failed (1.1)\n");
return(FALSE);
}
AttachCxObj(broker,obj);
if ((obj = CxCustom(dispatch_cx,NULL)) == NULL) {
dbprintf("cx: no key custom\n");
return(FALSE);
}
AttachCxObj(broker,obj);
if (CxObjError(broker)) {
dbprintf("cx failed (4)\n");
return(FALSE);
}
ActivateCxObj(broker,TRUE);
return(TRUE);
} /* open_cxstuff */
/*--------------------------------------------------------------------------*/
/* close_cxstuff */
/*--------------------------------------------------------------------------*/
void close_cxstuff(void)
{
if (broker != NULL)
DeleteCxObjAll(broker);
if (cxport != NULL)
DeletePort(cxport);
} /* close_cxstuff */
/*--------------------------------------------------------------------------*/
/* open_stuff */
/*--------------------------------------------------------------------------*/
BOOLEAN open_stuff(UINT argc, UCHAR *argv[])
{
UCHAR *str;
UINT i;
if ((GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",37L)) == NULL)
return(FALSE);
if ((IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library",37L)) == NULL)
return(FALSE);
if ((GadToolsBase = OpenLibrary("gadtools.library",37L)) == NULL)
return(FALSE);
if ((CxBase = OpenLibrary("commodities.library",37L)) == NULL)
return(FALSE);
if ((IconBase = OpenLibrary("icon.library",37L)) == NULL)
return(FALSE);
tooltypes = ArgArrayInit(argc,argv);
initial_popup = stricmp("yes",ArgString(tooltypes,CX_POPUP,DEF_CX_POPUP)) == 0;
newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY,DEF_CX_PRIORITY);
popup_key = ArgString(tooltypes, CX_POPKEY,DEF_CX_POPKEY);
blank_key = ArgString(tooltypes,CX_BLANKKEY,DEF_CX_BLANKKEY);
timeout_ticks = (ArgInt(tooltypes, TT_TIMEOUT, DEF_TIMEOUT) * TICKSPERMIN) / 60;
nr_objects = ArgInt(tooltypes, TT_NR_OBJECTS,DEF_NR_OBJECTS);
priority = ArgInt(tooltypes, TT_PRIORITY, DEF_PRIORITY);
mouse_timeout = ArgInt(tooltypes, TT_MOUSE_TIMEOUT, DEF_MOUSE_TIMEOUT);
if (mouse_timeout != -1L)
mouse_timeout = (mouse_timeout * TICKSPERMIN) / 60;
str = ArgString(tooltypes,TT_SPEED,DEF_SPEED);
for (i = 1; i < 4 && stricmp(str,delay_txt[i - 1]) != 0; i++)
;
delay_rate = i;
if (delay_rate == 4)
delay_rate = 2;
str = ArgString(tooltypes,TT_SLEEPCORNER,DEF_SLEEPCORNER);
for (i = 0; i < CO_DISABLED && stricmp(str,corner_txt[i]) != 0; i++)
;
csleep = i;
str = ArgString(tooltypes,TT_NEVERSLEEP,DEF_NEVERSLEEP);
for (i = 0; i < CO_DISABLED && stricmp(str,corner_txt[i]) != 0; i++)
;
cnever = i;
if (cnever == csleep)
cnever = CO_DISABLED;
if (! open_cxstuff())
return(FALSE);
return(TRUE);
} /* open_stuff */
/*--------------------------------------------------------------------------*/
/* close_stuff */
/*--------------------------------------------------------------------------*/
void close_stuff(void)
{
close_cxstuff();
ArgArrayDone();
if (IconBase != NULL)
CloseLibrary(IconBase);
if (CxBase != NULL)
CloseLibrary(CxBase);
if (GadToolsBase != NULL)
CloseLibrary(GadToolsBase);
if (IntuitionBase != NULL)
CloseLibrary((struct Library *) IntuitionBase);
if (GfxBase != NULL)
CloseLibrary((struct GfxBase *) GfxBase);
} /* close_stuff */
/*--------------------------------------------------------------------------*/
/* urand */
/*--------------------------------------------------------------------------*/
INT urand(INT limit)
{
static LONG random_seed = 0xDEAD0123;
random_seed = random_seed * custom.vhposr + 0xe153766f;
return ((INT) ((UINT) random_seed % limit));
} /* urand */
/*--------------------------------------------------------------------------*/
/* check_collision */
/*--------------------------------------------------------------------------*/
INT check_collision(INT i,INT x, INT y)
{
INT j,
jx,jy;
x += IM_WIDTH / 2;
y += IM_HEIGHT / 2;
for (j = 0; j < nr_objects; j++) {
if (j != i && ft[j].delay == 0) {
jx = ft[j].x + IM_WIDTH / 2;
jy = ft[j].y + IM_HEIGHT / 2;
if (((jx - x) * (jx - x) + (jy - y) * (jy - y)) <= (4 * IM_RADIUS * IM_RADIUS))
return(j);
}
}
return(-1);
} /* check_collision */
/*--------------------------------------------------------------------------*/
/* calc_new_pos */
/*--------------------------------------------------------------------------*/
void calc_new_pos(INT i)
{
INT x,y,
c;
x = ft[i].x - ft[i].speed;
y = ft[i].y + 2;
ft[i].old_x = ft[i].x;
ft[i].old_y = ft[i].y;
if ((c = check_collision(i,x,y)) != -1) {
x = ft[i].x;
y += 2;
if ((c = check_collision(i,x,y)) != -1) {
y = ft[i].y - 4;
if ((c = check_collision(i,x,y)) != -1)
return;
}
}
ft[i].x = x;
ft[i].y = y;
} /* calc_new_pos */
/*--------------------------------------------------------------------------*/
/* find_launch_pos */
/*--------------------------------------------------------------------------*/
BOOLEAN find_launch_pos(INT i)
{
BOOLEAN colides;
INT j,
x,y,
ix,iy,
jx,jy;
x = win->Width;
y = (urand(7) - 1) * IM_HEIGHT;
FOREVER {
if (x <= (2 * IM_WIDTH) && y <= - IM_HEIGHT)
return(FALSE);
ix = x + IM_WIDTH / 2;
iy = y + IM_HEIGHT / 2;
colides = FALSE;
for (j = 0; j < nr_objects && ! colides; j++) {
if (i != j) {
jx = ft[j].x + IM_WIDTH / 2;
jy = ft[j].y + IM_HEIGHT / 2;
if (((jx - ix) * (jx - ix) + (jy - iy) * (jy - iy)) <=
(4 * IM_RADIUS * IM_RADIUS)) {
colides = TRUE;
}
}
}
if (! colides) {
ft[i].x = ft[i].old_x = x;
ft[i].y = ft[i].old_y = y;
return(TRUE);
}
if (y > - IM_HEIGHT)
y -= IM_HEIGHT;
else
x -= IM_WIDTH;
}
} /* find_launch_pos */
/*--------------------------------------------------------------------------*/
/* goto_next_img */
/*--------------------------------------------------------------------------*/
void goto_next_img(struct object *obj, struct sequence *next_seq)
{
obj->phase++;
if (obj->phase >= obj->seq->img_count) {
obj->phase = 0;
if (next_seq == NULL) {
obj->seq = obj->seq->next_sequence;
if (urand(LOOPRATE) == 0) {
obj->rate = RATE_DEC - 1;
obj->seq = &loop_seq;
}
else if (urand(FACERATE) == 0) {
obj->rate = RATE_DEC - 1;
obj->seq = &face_seq;
}
}
else
obj->seq = next_seq;
}
} /* goto_next_img */
/*--------------------------------------------------------------------------*/
/* run_ft */
/*--------------------------------------------------------------------------*/
struct ft_msg * run_ft(void)
{
INT i;
struct ft_msg *ft_msg;
if (win != NULL)
return(NULL);
if (! open_display()) {
close_display();
return(NULL);
}
if (nr_objects == 0) {
ft_msg = (struct ft_msg *) WaitPort(ft_port);
close_display();
return(ft_msg);
}
for (i = 0; i < nr_objects; i++) {
memset(&ft[i],'\0',sizeof(ft[0]));
if (! find_launch_pos(i))
ft[i].delay = 30;
else
ft[i].delay = urand(50);
ft[i].phase = urand(IMAGEMAX);
ft[i].seq = &default_seq;
ft[i].speed = FT_SPEED;
ft[i].rate = ft[i].rate_count = FT_RATE(i);
}
while ((ft_msg = (struct ft_msg *) GetMsg(ft_port)) == NULL ||
ft_msg->ftm_action == BA_BLANK) {
if (ft_msg != NULL)
free(ft_msg);
for (i = 0; i < nr_objects; i++) {
if (ft[i].delay == 0) {
calc_new_pos(i);
ft[i].rate_count -= RATE_DEC;
if (ft[i].rate_count < 0) {
ft[i].rate_count = ft[i].rate;
goto_next_img(&ft[i], NULL);
}
if ((ft[i].old_x != ft[i].x || ft[i].old_y != ft[i].y)) {
if (ft[i].y > ft[i].old_y) {
EraseRect(win->RPort,ft[i].old_x,ft[i].old_y,
ft[i].old_x + IM_WIDTH,ft[i].y + 1);
}
if (ft[i].x < ft[i].old_x) {
EraseRect(win->RPort,ft[i].x + IM_WIDTH - 1,ft[i].y,
ft[i].old_x + IM_WIDTH,ft[i].old_y + IM_HEIGHT);
}
}
DrawImage(win->RPort,ft[i].seq->img[ft[i].phase],ft[i].x,ft[i].y);
if (ft[i].x < - (IM_WIDTH + 1) || ft[i].y > win->Height)
ft[i].delay = urand(50);
}
else {
ft[i].delay--;
if (ft[i].delay == 0) {
if (find_launch_pos(i)) {
ft[i].speed = FT_SPEED;
ft[i].rate = ft[i].rate_count = FT_RATE(i);
}
else
ft[i].delay = 30;
}
}
}
Delay(delay_rate);
}
close_display();
return(ft_msg);
} /* run_ft */
/*--------------------------------------------------------------------------*/
/* launch_ft */
/*--------------------------------------------------------------------------*/
void __saveds launch_ft(void)
{
enum BLANKERACTION action;
struct ft_msg *ft_msg;
if ((ft_port = CreatePort(FT_PORT_NAME,NULL)) == NULL)
return;
ft_msg = (struct ft_msg *) WaitPort(ft_port);
action = ft_msg->ftm_action;
free(ft_msg);
FOREVER {
blanked = FALSE;
switch (action) {
case BA_BLANK:
if (! blanked) {
blanked = TRUE;
ft_msg = run_ft();
}
break;
case BA_TERMINATE:
DeletePort(ft_port);
return;
case BA_POPUP_PREFS:
prefs_open = TRUE;
ft_msg = open_prefs();
prefs_open = FALSE;
break;
default:
if ((ft_msg = (struct ft_msg *) GetMsg(ft_port)) == NULL)
ft_msg = (struct ft_msg *) WaitPort(ft_port);
break;
} // switch
if (ft_msg != NULL) {
action = ft_msg->ftm_action;
free(ft_msg);
}
else
action = BA_WAIT;
} // FOREVER
} /* launch_ft */
/*--------------------------------------------------------------------------*/
/* main */
/*--------------------------------------------------------------------------*/
void main(UINT argc, UCHAR *argv[])
{
ULONG signal,
id,type;
CxMsg *cxmsg;
struct ft_msg *ft_msg;
struct Process *ft_proc;
#if ! defined(DEBUG)
if (! IS_KICK2_0) {
if (_Backstdout != NULL) {
Write(_Backstdout,requires_txt,strlen(requires_txt));
Close(_Backstdout);
}
return;
}
if (_Backstdout != NULL) {
if (argv[1][0] == '?') {
Write(_Backstdout,helpstring,strlen(helpstring));
Close(_Backstdout);
return;
}
Close(_Backstdout);
}
#else
if (argv[1][0] == '?') {
puts(helpstring);
return;
}
#endif
if ((main_task = FindTask(NULL)) == NULL)
return;
if (! open_stuff(argc,argv)) {
close_stuff();
return;
}
if ((ft_proc = create_process(FT_PROCNAME,launch_ft,FALSE)) == NULL) {
close_stuff();
return;
}
while(FindPort(FT_PORT_NAME) == NULL)
Delay(1L);
if (initial_popup && (ft_msg = init_ftmsg(BA_POPUP_PREFS)) != NULL)
PutMsg(ft_port,(struct Message *) ft_msg);
do {
signal = Wait(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D| 1L << cxport->mp_SigBit);
while ((cxmsg = (CxMsg *) GetMsg(cxport)) != NULL) {
id = CxMsgID(cxmsg);
type = CxMsgType(cxmsg);
ReplyMsg((struct Message *) cxmsg);
switch(type) {
case CXM_IEVENT:
switch(id) {
case BA_BLANK:
if (! blanked && (ft_msg = init_ftmsg(BA_BLANK)) != NULL)
PutMsg(ft_port, (struct Message *) ft_msg);
break;
case BA_POPUP_PREFS:
if (! prefs_open && (ft_msg = init_ftmsg(BA_POPUP_PREFS)) != NULL) {
PutMsg(ft_port, (struct Message *) ft_msg);
}
break;
} // switch
break;
case CXM_COMMAND:
switch (id) {
case CXCMD_DISABLE:
ActivateCxObj(broker,FALSE);
break;
case CXCMD_ENABLE:
ActivateCxObj(broker,TRUE);
break;
case CXCMD_APPEAR:
case CXCMD_UNIQUE:
if (! prefs_open && (ft_msg = init_ftmsg(BA_POPUP_PREFS)) != NULL) {
PutMsg(ft_port, (struct Message *) ft_msg);
}
break;
case CXCMD_DISAPPEAR:
if (prefs_open && (ft_msg = init_ftmsg(BA_WAIT)) != NULL) {
PutMsg(ft_port, (struct Message *) ft_msg);
}
break;
case CXCMD_KILL:
signal |= SIGBREAKF_CTRL_C;
break;
} // switch
break;
}
} // while
} while ((signal & (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D)) == 0L);
while(FindTask(FT_PROCNAME) != NULL) {
if ((ft_msg = init_ftmsg(BA_TERMINATE)) != NULL)
PutMsg(ft_port,(struct Message *) ft_msg);
Delay(10L);
}
close_stuff();
} /* main */